import { Injectable } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { BaiduToken } from './common/baidu_token';
import { firstValueFrom } from 'rxjs';

@Injectable()
export class AppService {
  constructor(private httpService: HttpService, private baiduToken: BaiduToken) {}

  // 参数校验，和ai模型的参数对齐的，简单加层校验，这里没列举全
  validateBody(body: any) {
    // 验证messages参数
    if (!Array.isArray(body.messages)) {
      throw new Error('messages必须为数组');
    }
    let totalContentLength = 0;
    for (const message of body.messages) {
      if (typeof message.role !== 'string' || typeof message.content !== 'string') {
        throw new Error('每个message必须有role和content属性');
      }
      totalContentLength += message.content.length;
    }
    if (totalContentLength > 20000) {
      throw new Error('messages中content总字符数不能超过20000字符');
    }

    // 验证temperature参数
    if (body.temperature !== undefined && (typeof body.temperature !== 'number' || body.temperature < 0 || body.temperature > 1)) {
      throw new Error('temperature必须在0-1之间');
    }

    // 验证stream参数
    if (body.stream !== undefined && typeof body.stream !== 'boolean') {
      throw new Error('stream必须是布尔值');
    }

    // 验证stop参数
    if (body.stop !== undefined) {
      if (!Array.isArray(body.stop)) {
        throw new Error('stop必须是数组');
      }
      for (const item of body.stop) {
        if (typeof item !== 'string' || item.length > 20) {
          throw new Error('stop内每个元素不能超过20字符');
        }
      }
      if (body.stop.length > 4) {
        throw new Error('stop 不能超过4个');
      }
    }

    // 验证max_output_tokens参数
    if (body.max_output_tokens !== undefined && (typeof body.max_output_tokens !== 'number' || body.max_output_tokens < 2 || body.max_output_tokens > 2048)) {
      throw new Error('max_output_tokens 必须为2-2048内的整数值');
    }
  }

  /**
 * 调用下一个API接口
 * @param body 请求体数据
 * @returns 返回API的响应数据
 */
  async callNextApi(body: any) {
    // 验证请求体数据
    this.validateBody(body);

    const tokenData = await this.baiduToken.getToken()

    // 构建请求参数和URL
    const params = {
      'access_token': tokenData.access_token
    };
    const url = 'https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro?' + new URLSearchParams(params);

    try {
      // 发起POST请求并处理响应
      const response = await firstValueFrom(
        this.httpService.post(url, body, {
          headers: {
            'Content-Type': 'application/json',
            'Accept': 'application/json',
          },
        })
      );
      const resData = response.data;
      // 如果返回错误码110，表示token过期，需要重置token
      if (resData.error_code === 110) {
        this.baiduToken.resetToken();
      }
      return resData;
    } catch (error) {
      console.error(error);
      throw new Error('获取回应失败');
    }
  }
}
